package com.fingard.dsp.bank.directbank.fuiou01;

import java.util.HashMap;
import java.util.Map;

import com.fingard.constant.Format;
import com.fingard.crypto.DigestHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingleBat;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingle;
import com.fingard.dsp.bank.reqrespobj.single.ReqSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingleBat;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * 富友直联单笔代付
 * 
 * @author Cruise
 * @date 2019/03/06
 */
public class FUIOU01SinglePay extends FUIOU01Base implements ISinglePay {
	/**
	 * 单笔代付提交
	 */
	public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
		RetAtsSglDetail tmpRetDetail = d_190802(p_req1908);

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/**
	 * 单笔代付提交
	 * 
	 * @param p_req1908
	 * @return
	 * @throws Exception
	 */
	private RetAtsSglDetail d_190802(ReqSingle p_req1908) throws Exception {
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "");
			if (actItem != null) {
				FUIOU01Header bankHeader = new FUIOU01Header();
				bankHeader.reqtype = "payforreq";

				Map<String, String> postParams = new HashMap<String, String>();
				postParams.put("merid", actItem.merchantId);
				postParams.put("reqtype", bankHeader.reqtype);

				XmlTextWriter xmlWriter = new XmlTextWriter();
				xmlWriter.writeStartDocByDeclaration(
						"<?xml version=\"1.0\" encoding=\"" + getCharset() + "\" standalone=\"yes\"?>");
				XElement tmpXElement = new XElement("payforreq", "");
				tmpXElement.addChild(new XElement("ver", "1.0"));
		        tmpXElement.addChild(new XElement("merdt", Format.Date8Format.format(p_req1908.singleDetail.getPayDateTime())));
		        tmpXElement.addChild(new XElement("orderno", p_req1908.singleDetail.askNumber));
		        tmpXElement.addChild(new XElement("bankno", getBankConfig().getMapValueByKey("bankMapping", p_req1908.singleDetail.recBankCode)));
		        tmpXElement.addChild(new XElement("cityno", p_req1908.singleDetail.recArea));
		        String cnapsName = p_req1908.singleDetail.cnapsName;
		        if (StringHelper.isNullOrEmpty(cnapsName)) {
		        	cnapsName = p_req1908.singleDetail.recBankLocation;
		        }
		        tmpXElement.addChild(new XElement("branchnm", cnapsName));
		        tmpXElement.addChild(new XElement("accntno", p_req1908.singleDetail.recAct));
		        tmpXElement.addChild(new XElement("accntnm", p_req1908.singleDetail.recName));
		        tmpXElement.addChild(new XElement("amt", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount)));
		        tmpXElement.addChild(new XElement("entseq", p_req1908.singleDetail.askNumber));
		        tmpXElement.addChild(new XElement("memo", p_req1908.singleDetail.memo));
		        tmpXElement.addChild(new XElement("mobile", p_req1908.singleDetail.cellPhone));
		        tmpXElement.addChild(new XElement("addDesc", "1"));
		        nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());
		        xmlWriter.writeXElement(tmpXElement);
		        xmlWriter.writeEndDocument();

				String reqStr = actItem.merchantId + "|" + actItem.saltKey + "|" + bankHeader.reqtype + "|"
						+ xmlWriter.toXmlString();
				String mac = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));

				postParams.put("xml", xmlWriter.toXmlString());
				postParams.put("mac", mac);

				String[] tmpStrRet = sendToBank("generalPay", postParams);

				if (tmpStrRet[0].length() == 0) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

					if (tmpBkReader != null) {
						String tmpRespCode = tmpBkReader.getFirstText("/payforrsp/ret");
						String tmpRespInfo = tmpBkReader.getFirstText("/payforrsp/memo");
						String transStatusDesc = tmpBkReader.getFirstText("/payforrsp/transStatusDesc");

						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = tmpRespInfo;
						tmpRetDetail.transAmt = p_req1908.singleDetail.payAmount;
						tmpRetDetail.transState = StringHelper.joinNotEmpty("+", tmpRespCode, transStatusDesc);
						tmpRetDetail.payInfoCode = tmpRetDetail.transState;
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpSbMsg.toString();
					}
				} else if (tmpStrRet[0].equals(ConnState.FAIL)) {
					tmpRetDetail.respCode = "0";
					tmpRetDetail.respInfo = tmpStrRet[1];
					tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
					tmpRetDetail.transState = PaymentState.FAIL_Payment;
					tmpRetDetail.payInfoCode = tmpStrRet[0];
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpStrRet[1];
				}
			} else {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到账号[" + p_req1908.singleDetail.payAct + "]商户配置信息!";
				tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = FailCode.E9981;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "0";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		return tmpRetDetail;
	}

	/**
	 * 单笔代付状态查询
	 */
	public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		tmpRetDetail.reqSeqID = p_req1944.askNumber;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "");
			if (actItem != null) {
				FUIOU01Header bankHeader = new FUIOU01Header();
				bankHeader.reqtype = "qrytransreq";

				Map<String, String> postParams = new HashMap<String, String>();
				postParams.put("merid", actItem.merchantId);
				postParams.put("reqtype", bankHeader.reqtype);

				XmlTextWriter xmlWriter = new XmlTextWriter();
				xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\" standalone=\"yes\"?>");
				xmlWriter.writeStartElement("qrytransreq");
				xmlWriter.writeElementString("ver", "1.0");
				xmlWriter.writeElementString("busicd", "AP01");
				xmlWriter.writeElementString("orderno", p_req1944.askNumber);
				String transDate = Format.Date8Format.format(p_req1944.getBgnDateTime());
				xmlWriter.writeElementString("startdt", transDate);
				xmlWriter.writeElementString("enddt", transDate);
				xmlWriter.writeElementString("transst", "");
				xmlWriter.writeElementString("srcModuleCd", "HMP");
				xmlWriter.writeEndElement();
				xmlWriter.writeEndDocument();

				String reqStr = actItem.merchantId + "|" + actItem.saltKey + "|" + bankHeader.reqtype + "|" + xmlWriter.toXmlString(); 
				String mac = DigestHelper.cryptoMD5RetHexStr(reqStr.getBytes(getCharset()));

				postParams.put("xml", xmlWriter.toXmlString());
				postParams.put("mac", mac);

				String[] tmpStrRet = sendToBank("generalPay", postParams);

				if (tmpStrRet[0].length() == 0) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
					if (tmpBkReader != null) {
						String tmpRespCode = tmpBkReader.getFirstText("/qrytransrsp/ret");
						String tmpRespInfo = tmpBkReader.getFirstText("/qrytransrsp/memo");
						if (tmpRespCode.equals("000000")) {
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = tmpRespInfo;
							tmpRetDetail.reqSeqID = p_req1944.askNumber;
							tmpRetDetail.transState = tmpRespCode + "+"	+ tmpBkReader.getFirstText("/qrytransrsp/trans/state");
							tmpRetDetail.payInfoCode = tmpRespCode;
							tmpRetDetail.transAmt = StringHelper.amountDivide100(tmpBkReader.getFirstText("/qrytransrsp/trans/amt"));
							
							tmpRespInfo = tmpBkReader.getFirstText("/qrytransrsp/trans/reason");
							if (StringHelper.hasAnyChar(tmpRespInfo)) {
								tmpRetDetail.respInfo = tmpRespInfo;
								tmpRespInfo = tmpBkReader.getFirstText("/qrytransrsp/trans/result");
								if (StringHelper.hasAnyChar(tmpRespInfo)) {
									tmpRetDetail.respInfo = tmpRespInfo;
								}
							}
						} else {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = tmpRespInfo;
						}
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpSbMsg.toString();
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = tmpStrRet[1];
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号[" + p_req1944.payAct + "]商户配置信息!";
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	@Override
	public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
		return null;
	}

	@Override
	public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
		return null;
	}
}
